//
//  TestSprite.cpp
//  NanoOSX
//
//  Created by Jeppe Nielsen on 9/9/13.
//  Copyright (c) 2013 Jeppe Nielsen. All rights reserved.
//

#include "Engine.hpp"
#include "GameState.hpp"
#include "GameWorld.hpp"
#include "RenderSystem.hpp"
#include "Touchable.hpp"
#include "Material.hpp"
#include "TextureComponent.hpp"
#include "FirstPersonMoverSystem.hpp"
#include "TouchSystem.hpp"
#include "Light.hpp"
#include "SpriteMeshSystem.hpp"
#include "LabelMeshSystem.hpp"
#include "TransformHierarchy.hpp"
#include "SpriteTextureSystem.hpp"
#include "Plane.hpp"
#include "Timer.hpp"

using namespace Nano;
using namespace std;

class TestGUI : public GameState<TestGUI> {
    void Initialize() {
        renderTime = 0;
        renderCounter = 0;
        
        renderer = world.CreateSystem<RenderSystem>();
        world.CreateSystem<FirstPersonMoverSystem>()->Input = &Input;
        world.CreateSystem<TouchSystem>()->Input = &Input;
        world.CreateSystem<SpriteMeshSystem>();
        world.CreateSystem<LabelMeshSystem>();
        world.CreateSystem<TransformHierarchy>();
        world.CreateSystem<SpriteTextureSystem>();
        
        atlas = world.CreateObject();
        atlas->AddComponent<Atlas>()->Load("images.xml", 1024);
        atlas->AddComponent<TextureComponent>()->Texture().LoadFromPng("images.png");
        
        GameObject* font = world.CreateObject();
        font->AddComponent<Font>()->Load("OtherFont.fnt", "OtherFont");
        
        camera = world.CreateObject();
        camera->AddComponent<FirstPersonMover>();
        camera->AddComponent<Camera>()->Viewport = Manager().Viewport();
        camera->AddComponent<Transform>()->Position = Vector3(0,0,4);
        cam = camera->GetComponent<Camera>();
        
        gadget = world.CreateObject();
        gadget->AddComponent<Transform>()->Position = Vector3(0,0,-0.05f);
        gadget->AddComponent<Mesh>();
        gadget->AddComponent<Material>()->BlendMode = BlendMode::Alpha;
        gadget->AddComponent<Sizeable>()->Size = Vector2(3,3);
        gadget->AddComponent<Sprite>()->SpriteName = "Button";
        //gadget->AddComponent<Colorable>()->Color = Colour::White();
        gadget->AddComponent<Atlas>(atlas);
        gadget->AddComponent<TextureComponent>(atlas);
        gadget->GetComponent<Sprite>()->CornerSize = 0.3f;
        
        for (int x=0; x<100; x++) {
            for (int y=0; y<100; y++) {
                CreateGadget(gadget, Vector2(x,y), 0.6f+x*0.03f);
            }
        }
        
        /*
        label = world.CreateObject();
        label->AddComponent<Transform>()->Position = Vector3(10,3,1) * 0.5f;
        label->AddComponent<Mesh>();
        label->AddComponent<Material>()->LightingEnabled = false;
        label->GetComponent<Material>()->BlendMode = BlendMode::Alpha;
        label->AddComponent<Font>(font);
        label->AddComponent<Atlas>(atlas);
        label->AddComponent<TextureComponent>(atlas);
        label->AddComponent<Label>()->Text = "Click me";
        label->AddComponent<Sizeable>()->Size = Vector2(0,0);
        label->GetComponent<Label>()->WordWrap = false;
        label->GetComponent<Label>()->HAlignment = Font::Center;
        label->GetComponent<Label>()->VAlignment = Font::Middle;
         
         */
        
    }
    
    void CreateGadget(GameObject* parent, Vector2 position, Vector2 size) {
        
        
        GameObject* gadget = world.CreateObject();
        gadget->Parent = parent;
        gadget->AddComponent<Transform>()->Position = Vector3(position.x,position.y,-0.05f);
        gadget->AddComponent<Mesh>();
        gadget->AddComponent<Material>()->BlendMode = BlendMode::Alpha;
        gadget->GetComponent<Material>()->DepthEnabled = false;
        gadget->AddComponent<Sizeable>()->Size = size;
        gadget->AddComponent<Sprite>()->SpriteName = "Button";
        //gadget->AddComponent<Colorable>()->Color = Colour::Blue();
       // gadget->AddComponent<Hierarchy>()->Parent = parent->GetComponent<Hierarchy>();
        gadget->AddComponent<Atlas>(atlas);
        gadget->AddComponent<TextureComponent>(atlas);
        //gadget->GetComponent<Sprite>()->CornerSize = size * 0.1f;
        
    }
    
    
    void Update(float dt) {

        static float rotation = 0;
        rotation+=dt;
        
        if (gadget) {
            Plane plane(Vector3(0,0,1),0);
            float dist;
            Ray ray = cam->GetRay(camera->GetComponent<Transform>(), Input.GetTouchPosition(0));
            if (plane.IntersectsRay(ray, &dist)) {
                //gadget->GetComponent<Transform>()->Position = ray.position + ray.direction * dist;
            }
        }
        gadget->GetComponent<Transform>()->Rotation = rotation;

        world.Update(dt);
    }
    
    void Render() {
        glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glEnable(GL_CULL_FACE);
        renderTimer.Begin();
        renderer->Render();
        renderTime += renderTimer.End();
        renderCounter++;
        if (renderCounter>20) {
            renderTime /= renderCounter;
            cout<<"Render() time = " << (1.0 / renderTime) << endl;
            renderCounter=0;
        }
    }
    
    GameWorld world;
    RenderSystem* renderer;
    GameObject* gadget;
    GameObject* label;
    GameObject* atlas;
    Camera* cam;
    GameObject* camera;
    Timer renderTimer;
    double renderTime;
    int renderCounter;
};

/*
int main() {
    Engine e;
    e.Start<TestGUI>();
}

*/





